package nc.gl.assautoconfig.util;

import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.itf.gl.pub.IFreevaluePub;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.pubitf.bd.accessor.GeneralAccessorFactory;
import nc.pubitf.bd.accessor.IGeneralAccessor;
import nc.vo.bd.accassitem.AccAssItemVO;
import nc.vo.bd.accessor.IBDData;
import nc.vo.bd.account.AccountVO;
import nc.vo.fipub.freevalue.GlAssVO;
import nc.vo.fipub.freevalue.Module;
import nc.vo.gateway60.itfs.AccountUtilGL;
import nc.vo.gl.assautoconfig.AggAssautoconfigMasterVO;
import nc.vo.gl.assautoconfig.AssautoconfigMasterVO;
import nc.vo.gl.assautoconfig.AssautoconfigSlave0VO;
import nc.vo.glcom.ass.AssVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nccloud.dto.gl.lightgl.displayformattool.ShowContentCenter;
import org.apache.commons.lang3.StringUtils;
import org.mvel2.ast.BooleanNode;

import java.util.*;
import java.util.stream.Collectors;

public class ValidateUtil {
    public static final String SEPARATOR = "##";

    public static void saveAfterValidate(AggAssautoconfigMasterVO aggVO) {
        if (aggVO == null) {
            return;
        }
        AssautoconfigMasterVO parentVO = aggVO.getParentVO();
        if (parentVO == null) {
            return;
        }
        String pkAccountingbook = parentVO.getPk_accountingbook();
        String asoaversion = parentVO.getAsoaversion();
        String configtype = parentVO.getConfigtype();
        IUAPQueryBS iuapQueryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class);
        String sql = " select count(1) from gl_assautoconfigmaster where dr=0 " +
                " and pk_accountingbook='" + pkAccountingbook + "' and asoaversion='" + asoaversion + "' and configtype='" + configtype + "' ";
        try {
            Integer count = (Integer) iuapQueryBS.executeQuery(sql, new ColumnProcessor());
            if (count > 1) {
                ExceptionUtils.wrappBusinessException("下列字段信息重复，核算账簿+科目版本+携带类型!");
            }
        } catch (BusinessException e) {
            Logger.error("查询出错...");
        }
    }

    //重置一下行号,包括页面传过来的和导入的数据
    public static void resetRowNo(AggAssautoconfigMasterVO aggVO) {
        if (aggVO == null) {
            return;
        }
        AssautoconfigSlave0VO[] slave0VOS = (AssautoconfigSlave0VO[]) aggVO.getChildrenVO();
        if (slave0VOS == null || slave0VOS.length == 0) {
            return;
        }
        int rowno = 1;
        for (AssautoconfigSlave0VO slave0VO : slave0VOS) {
            //删除行不要给行号
            if (slave0VO.getStatus() == VOStatus.DELETED) {
                continue;
            }
            if (slave0VO.getStatus() == VOStatus.UNCHANGED) {
                slave0VO.setStatus(VOStatus.UPDATED);
            }
            slave0VO.setRowno(String.valueOf(rowno));
            rowno++;
        }
    }

    public static void saveBeforeValidate(AggAssautoconfigMasterVO aggVO) {
        if (aggVO == null) {
            return;
        }

        AssautoconfigMasterVO parentVO = aggVO.getParentVO();
        if (parentVO == null) {
            return;
        }
        String configtype = parentVO.getConfigtype();
        String pk_accountingbook = parentVO.getPk_accountingbook();
        String asoaversion = parentVO.getAsoaversion();
        if (StringUtils.isEmpty(configtype)) {
            ExceptionUtils.wrappBusinessException("携带类型必填!");
        }
        AssautoconfigSlave0VO[] slave0VOS = (AssautoconfigSlave0VO[]) aggVO.getChildrenVO();
        if (slave0VOS == null || slave0VOS.length == 0) {
            ExceptionUtils.wrappBusinessException("表体数据不能为空!");
            return;
        }
        boolean allEmpty = Arrays.stream(slave0VOS).allMatch(slave0VO -> slave0VO.getStatus() == VOStatus.DELETED);
        if (allEmpty) {
            ExceptionUtils.wrappBusinessException("表体数据不能为空!");
            return;
        }
        Set<String> pk_accassoas = new HashSet<>();
        Set<String> assids = new HashSet<>();
        for (AssautoconfigSlave0VO slave0VO : slave0VOS) {
            pk_accassoas.add(slave0VO.getPk_accassoa());
            assids.add(slave0VO.getZassid());
            if (slave0VO.getFassid()!=null){
                assids.add(slave0VO.getFassid());
            }
        }
        // AccountVO[] accountVOS = AccountUtilGL.queryByPks(pk_accassoas.toArray(new String[0]), asoaversion);
        // Map<String, AccountVO> accountVOMap = Arrays.stream(accountVOS).collect(Collectors.toMap(AccountVO::getPk_accasoa, AccountVO -> AccountVO));
        GlAssVO[] glAssVOS=null;
        IFreevaluePub iFreevaluePub = NCLocator.getInstance().lookup(IFreevaluePub.class);
        try {
            glAssVOS = iFreevaluePub.queryAllByIDs(assids.toArray(new String[0]), null, Module.GL);
        } catch (BusinessException e) {

        }
        Map<String, GlAssVO> glAssVOMap = Arrays.stream(glAssVOS).collect(Collectors.toMap(GlAssVO::getAssID, GlAssVO -> GlAssVO));
        Map<String, List<Integer>> map = new LinkedHashMap<>();
        StringBuilder zfMsg = new StringBuilder();
        StringBuilder assNullMsg = new StringBuilder();
        StringBuilder leafMsg = new StringBuilder();
        String rowMsg = null;
        AssautoconfigUtil assautoconfigUtil = new AssautoconfigUtil();
        for (int i = 0; i < slave0VOS.length; i++) {
            AssautoconfigSlave0VO slave0VO = slave0VOS[i];
            if (slave0VO.getStatus() == VOStatus.DELETED) {
                continue;
            }
            int rownum = Integer.valueOf(slave0VO.getRowno());
            rowMsg = "第" + rownum + "行,";
            boolean assNullFlag = false;
            String key = slave0VO.getPk_accassoa();
            String zassid = slave0VO.getZassid();
            if (StringUtils.isEmpty(zassid)) {
                continue;
            }
            AssVO[] assVOS = new AssVO[0];
            try {
                //assVOS = iFreevaluePub.queryAssvosByid(zassid, Module.GL);
                GlAssVO glAssVO = glAssVOMap.get(zassid);
                if(glAssVO == null){
                    continue;
                }
                assVOS = glAssVOMap.get(zassid).getAssVos();
                if (assautoconfigUtil.isAllEmpty(assVOS)) {
                    assNullFlag = true;
                    assNullMsg.append(rowMsg + ("1".equals(configtype) ? "辅助核算不能为空;\n" : "辅助核算或携带辅助核算不能为空;\n"));
                }
                if ("1".equals(configtype)){
                    StringBuilder builderLeafMsg = new StringBuilder();
                    for (AssVO assVO : assVOS) {
                        String pkChecktype = assVO.getPk_Checktype();
                        AccAssItemVO accAssItem = AccAssItemProxy.getInstance().getAccAssItem(pkChecktype);
                        IGeneralAccessor accessor = GeneralAccessorFactory.getAccessor(accAssItem.getClassid());
                        List<IBDData> childDocs = accessor.getChildDocs(parentVO.getPk_org(), assVO.getPk_Checkvalue(), false);
                        if (childDocs!=null&&childDocs.size()>0){
                            builderLeafMsg.append("表体辅助核算列的辅助核算项:"+assVO.getChecktypename()+",不能选择非末级数据;");

                        }
                    }
                    if (builderLeafMsg!=null&&!"".equals(builderLeafMsg.toString())){
                        leafMsg.append(rowMsg+builderLeafMsg+"\n");
                    }

                }

                if ("2".equals(configtype)) {
                    key = key + SEPARATOR + zassid;
                    String fassid = slave0VO.getFassid();
                    //AssVO[] assVOS1 = iFreevaluePub.queryAssvosByid(fassid, Module.GL);
                    GlAssVO glAssVO1 = glAssVOMap.get(fassid);
                    if (glAssVO1 == null) {
                        continue;
                    }
                    AssVO[] assVOS1 = glAssVOMap.get(fassid).getAssVos();
                    StringBuilder builderLeafMsg = new StringBuilder();
                    for (AssVO assVO : assVOS1) {
                        String pkChecktype = assVO.getPk_Checktype();
                        AccAssItemVO accAssItem = AccAssItemProxy.getInstance().getAccAssItem(pkChecktype);
                        IGeneralAccessor accessor = GeneralAccessorFactory.getAccessor(accAssItem.getClassid());
                        List<IBDData> childDocs = accessor.getChildDocs(parentVO.getPk_org(), assVO.getPk_Checkvalue(), false);
                        if (childDocs!=null&&childDocs.size()>0){
                            builderLeafMsg.append("表体携带辅助核算列的辅助核算项:"+assVO.getChecktypename()+",不能选择非末级数据;");
                        }
                    }
                    if (builderLeafMsg!=null&&!"".equals(builderLeafMsg.toString())){
                        leafMsg.append(rowMsg+builderLeafMsg+"\n");
                    }
                    if (!assNullFlag && assautoconfigUtil.isAllEmpty(assVOS1)) {
                        assNullMsg.append(rowMsg + ("1".equals(configtype) ? "辅助核算不能为空;\n" : "辅助核算或携带辅助核算不能为空;\n"));
                    }
                    if (assVOS != null && assVOS.length > 0
                            && assVOS1 != null && assVOS1.length > 0) {
                        for (AssVO assVO : assVOS) {
                            for (AssVO vo : assVOS1) {
                                if (assVO.getPk_Checktype().equals(vo.getPk_Checktype())) {
                                    if (assVO.getPk_Checkvalue() != null && !assVO.getPk_Checkvalue().equals("~")) {
                                        if (vo.getPk_Checkvalue() != null && !vo.getPk_Checkvalue().equals("~")) {
                                            zfMsg.append(rowMsg + "辅助核算的核算项有值,携带辅助核算的同辅助核算项则不能有值;\n");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (!map.containsKey(key)) {
                    map.put(key, new ArrayList<>());
                }
                map.get(key).add(rownum);
            } catch (BusinessException e) {
                Logger.error(e.getMessage());
            }
        }
        if (leafMsg != null && leafMsg.length() > 0) {
            ExceptionUtils.wrappBusinessException(leafMsg.toString());
        }
        if (assNullMsg != null && assNullMsg.length() > 0) {
            ExceptionUtils.wrappBusinessException(assNullMsg.toString());
        }
        if (zfMsg != null && zfMsg.length() > 0) {
            ExceptionUtils.wrappBusinessException(zfMsg.toString());
        }
        StringBuilder msg = new StringBuilder();

        for (String key : map.keySet()) {
            List<Integer> rows = map.get(key);
            if (rows != null && rows.size() >= 2) {
                String[] split = key.split(SEPARATOR);
                String pk_accassoa = split[0];
                String tmpMsg = "会计科目：" + ShowContentCenter.getShowAccsubj(pk_accountingbook, pk_accassoa, asoaversion);
                if (split.length == 2) {
                    String assid = split[1];
                    //GlAssVO[] glAssVos = iFreevaluePub.queryAllByIDs(new String[]{assid}, null, Module.GL);
                    GlAssVO glAssVos = glAssVOMap.get(assid);
                    if (glAssVos != null) {
                        tmpMsg += "，辅助核算：" + ShowContentCenter.getShowAss(pk_accountingbook, pk_accassoa, asoaversion, glAssVos.getAssVos());
                    }

                }
                msg.append("第" + StringUtils.join(rows, "、") + "行," + (tmpMsg) + "\n");

            }
        }
        //下列字段信息重复,
        if (msg != null && msg.length() > 0) {
            ExceptionUtils.wrappBusinessException("下列字段信息重复:\n" + msg.toString());
        }

    }

}
